/*******************************************************************************
 * Package: com.song.boot.springstudy.design.duty
 * Type:    PackCheck
 * Date:    2022-12-29 23:21
 *
 * Copyright (c) 2022 HUANENG GUICHENG TRUST CORP.,LTD All Rights Reserved.
 *
 * You may not use this file except in compliance with the License.
 *******************************************************************************/
package com.song.boot.springstudy.design.duty;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 * 功能描述： 封装 校验
 * https://juejin.cn/post/7023536216138055716 设计模式
 * https://blog.csdn.net/qq_40093255/article/details/117317943  ApplicationContextAware解释
 * 配置文件：https://www.cnblogs.com/jiujuan/p/16700983.html
 * 帮助文档：https://www.jianshu.com/p/630560194d00
 *
 * @author Songxianyang
 * @date 2022-12-29 23:21
 */
@Component
public class PackCheck implements ApplicationContextAware {
    // 配置需要注入
    @Resource
    private CheckConfig checkConfig;
    // 线程安全
    private List<AbstractCheck> listCheck = new CopyOnWriteArrayList<>();

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        Map<String, AbstractCheck> beansOfType = applicationContext.getBeansOfType(AbstractCheck.class);
        // 按照自己的配置顺序来进行校验
        checkConfig.getSortBeanNames().forEach(beanName -> {
            listCheck.add(beansOfType.get(beanName));
        });
    }

    // 执行当前 校验ListCheck
    public void runCheck(LeaveVO vo) {
        for(int i = 0;i<listCheck.size();i++){
            AbstractCheck currentCheck;
            if (i == 0) {
                currentCheck = listCheck.get(i);
                // 当前
                currentCheck.check(vo);
            } else {
                currentCheck = listCheck.get(i - 1);
                AbstractCheck nextCheck = listCheck.get(i);
                currentCheck.setAbstractCheckNext(nextCheck);
                // 防止重复执行
                currentCheck.next(vo);
            }
        }
    }
    // 精简
    public void runCheckFor(LeaveVO vo){
        if (!CollectionUtils.isEmpty(listCheck)) {
            for (AbstractCheck abstractCheck : listCheck) {
                abstractCheck.check(vo);
            }
        }
    }

    // 原始写法：硬编码

    public  void runCheckTest(LeaveVO vo) {
        AbstractCheck nullCheck = new NullCheck();
        nullCheck.check(vo);
        nullCheck.setAbstractCheckNext(new DaysCheck());
        nullCheck.next(vo);

    }

}
